// api
import{ getTaskCloseList, closeBatch, getTaskCloseListInitData, checkNotNullForCard, closeApproveCheck, checkNeedVipApprove, getCurrentAllTaskTypeList } from '@src/api/TaskApi'
/* business */
import BizListViewTask from '@src/component/business/BizListView/Impl/BizListViewTask/BizListViewTask.tsx'
/* components */
import ProposeApproveDialog from '@src/modules/task/view/components/ProposeApproveDialog.vue'
/* enum */
import ComponentNameEnum from '@model/enum/ComponentNameEnum'
import StorageKeyEnum from '@model/enum/StorageKeyEnum'
import AuthEnum from '@model/enum/AuthEnum'
/* entity */
import Field from '@model/entity/Field'
import EsTask from '@model/entity/EsTask'
/* model */
import { getTaskCloseInitDataResult, getTaskSearchListResult } from '@model/param/out/Task'
import { getColumnFields, getAdvancedFields } from '@src/modules/task/taskTypes/close/fields'
import { BatchCloseTaskMessage, BATCH_CLOSE_SUCCESS_MESSAGE, CLOSE_SUCCESS_MESSAGE, CONFIRM_CLOSE_TASK_MESSAGE } from '@src/model/const/Alert'
import Column from '@model/types/Column'
import { BizTableTaskScopeSlot } from '@src/component/business/BizTable/BizTableTask'
import { commonUseItemType } from '@src/component/AdvancedSearch/advancedSearch'
/* scss */
import '@src/modules/task/taskTypes/close/TaskCloseList.scss'
/* vue */
import { Component, Ref } from 'vue-property-decorator'
import { CreateElement } from 'vue'
import { VNode } from 'vue'
/* util */
import { strConcat as concat } from 'pub-bbx-utils'
import Platform from '@src/util/platform'
import LogUtil from '@src/util/log.ts'
import AuthUtil from '@src/util/auth'
import { isClosedTask, isInApprove } from '@service/TaskService'
import Log from '@src/util/log.ts'
import TaskApprove from '@model/entity/TaskApprove'
import * as _ from 'lodash';
import { storageSet, storageGet } from '@src/util/storageV2';
import i18n from '@src/locales'

import StorageUtil from '@src/util/storage.ts';
import StorageModuleEnum from '@model/enum/StorageModuleEnum';
@Component({ 
  name: ComponentNameEnum.TaskCloseList,
  components: {
    [ProposeApproveDialog.name]: ProposeApproveDialog
  }
})
export default class TaskCloseList extends BizListViewTask<EsTask> {
  
  // 工单审批弹窗
  @Ref() readonly ProposeApproveDialogComponent!: ProposeApproveDialog
  
  /* 高级搜索字段缓存数据 */
  public advancedSearchFieldStorageKey: StorageKeyEnum = StorageKeyEnum.TaskCloseListSearchFields
  /* 列数据 */
  public columns: Column[] = this.getColumnFields(this) as Column[]
  /* 初始数据 */
  public initData: getTaskCloseInitDataResult = {
    taskTypeList: [],
    taskConfig: undefined,
    paymentConfig: undefined
  }
  /* 选择列 缓存键名 */
  public selectColumnStorageKey: StorageKeyEnum = StorageKeyEnum.TaskCloseTableColumns
  /* pageSize 缓存键名 */
  public pageSizeStorageKey: StorageKeyEnum = StorageKeyEnum.TaskClosePageSize
  /* 关闭需要审批的工单id */
  private taskApproveId: string = ''
  private taskNo: any = ''
  
  /**
   * @description: 是否允许批量关闭
   * @return {boolean}
   */
  get allowTaskBatchClose(): boolean {
    return AuthUtil.hasAuth(this.auth, AuthEnum.TASK_BATCH_CLOSE)
  }
  
  /**
   * @description: 批量关闭事件
   * @return {void}
   */  
  public async batchCloseTaskHandler(): Promise<void | boolean> {
    // @ts-ignore
    this.$track.clickStat(this.$track.formatParams('BATCH_CLOSE'));
    const validated = this.selectedTaskDataValidate()
    if (!validated) return
    
    try {
      const confirm = await Platform.confirm(BatchCloseTaskMessage(this.selectedIds.length))
      if (!confirm) return
      
      this.loading = true
      
      const params = { ids: concat(this.selectedIds) }
      const result = await closeBatch(params)
      const success = result?.succ
      if (!success) {
        return Platform.alert(result?.message)
      }
      
      Platform.alert(BATCH_CLOSE_SUCCESS_MESSAGE)

      this.refresh()
      
    } catch (error) {
      LogUtil.error(error, this.batchCloseTaskHandler.name)
    } finally {
      this.loading = false
    }
  }
  
  /**
   * @description 关闭工单
   * @param {EsTask} task 工单数据
   * @return {void}
   */  
  private async closeTask(task: EsTask): Promise<void | boolean> {
    const confirm = await Platform.confirm(CONFIRM_CLOSE_TASK_MESSAGE);
    if(!confirm) return
    
    try {
      // 检查附件组件是否必填
      // const checkNotNullForCardParams = { id: task.id, flow: TaskFlowEnum.Close }
      // const checkNotNullForCardResult = await checkNotNullForCard(checkNotNullForCardParams)
      // 附件组件需要必填
      // if(!checkNotNullForCardResult?.succ) {
      //   return Platform.alert(checkNotNullForCardResult.message)
      // }

      // 先判断是否需要高级审批
      let approveParams = {
        taskId: task.id,
        action: 'close'
      }

      const approveResult = await checkNeedVipApprove(approveParams);
      if (approveResult.success && approveResult.result.needVipApprove) {
        this.taskApproveId = task.id
        this.taskNo = task.taskNo
        this.openProposeApproveDialog(approveResult?.result as TaskApprove)
        return
      }


      
      // 关闭工单
      const closeTaskResult = await closeApproveCheck({ id: task.id })
      
      // 不需要审批，刷新页面
      if(closeTaskResult?.succ) {
        Platform.alert(CLOSE_SUCCESS_MESSAGE)
        return this.refresh()
      }
      
      // TODO 需要审批判断改成errorCode
      if (Number(closeTaskResult?.errorCode) == 10003) {
        this.taskApproveId = task.id
        this.taskNo = task.taskNo
        this.openProposeApproveDialog(closeTaskResult?.data as TaskApprove)
        return;
      }

      if(!closeTaskResult.succ) {
        return Platform.alert(closeTaskResult.message)
      }
      
    } catch (error) {
      Log.error(error, this.closeTask.name)
    }
  }
  
  /**
   * @description: 获取高级搜索字段列表
   * @param {BizListViewTask} vm 当前实例
   * @return {Field[]} 高级搜索字段列表
   */  
  public getAdvancedFields(vm: BizListViewTask): Field[] {
    // 基础版过滤产品、结算时间、支付方式、曾打印字段
    let advancedFields = getAdvancedFields(vm).filter(field => field.show)
    if (this.isBasicEditionHideProduct) {
      advancedFields = advancedFields.filter(field => field.fieldName !== 'product')
    }
    if (this.isBasicEditionHidePrintTask) {
      advancedFields = advancedFields.filter(field => field.fieldName !== 'oncePrinted')
    }
    if (this.isBasicEditionHidePay) {
      advancedFields = advancedFields.filter(field => field.fieldName !== 'balanceTime' && field.fieldName !== 'paymentMethod')
    }

    return advancedFields
  }
  
  /**
   * @description: 获取表格列字段列表
   * @param {BizListViewTask} vm 当前实例
   * @return {Field[]} 表格列字段列表
   */  
  public getColumnFields(vm: BizListViewTask): Field[] {
    // 基础版过滤产品、结算时间、支付方式、曾打印字段
    let columnFields = getColumnFields(vm);
    if (this.isBasicEditionHideProduct) {
      columnFields = columnFields.filter(field => field.fieldName !== 'product')
    }
    if (this.isBasicEditionHidePrintTask) {
      columnFields = columnFields.filter(field => field.fieldName !== 'oncePrinted')
    }
    if (this.isBasicEditionHidePay) {
      columnFields = columnFields.filter(field => field.fieldName !== 'balanceTime' && field.fieldName !== 'paymentMethod')
    }

    return columnFields
  }
  
  /** 
   * @description 获取属性
  */
  public getAttributes() {
    const classNames: string[] = [ComponentNameEnum.TaskCloseList, 'common-list-container__v2']
    
    return {
      class: classNames,
      directives: [
        // {
        //   name: 'loading',
        //   value: this.loading
        // }
      ]
    }
  }
  
  public fetchTableListData() {
    const params = {
      ...this.searchParams,
      ...this.advancedSearchModel,
    }
    
    this.fetchTaskList(params, getTaskCloseList)
  }
  
  /**
   * @description: 获取初始化数据
   * @return {Promise<void>}
   */  
  public async fetchInitData(): Promise<void> {
    this.loading = true
    
    return (
      getTaskCloseListInitData()
        .then(async (result: getTaskCloseInitDataResult) => {
          this.initData = result
          this.taskTypes = result?.taskTypeList || []
          this.taskConfig = result?.taskConfig || null
          this.auth = result?.authorities || {}
          this.paymentConfig = result?.paymentConfig || null
        })
        .catch(err => {
          console.error(err)
        })
    )
  }
  
  /**
   * @description: 初始化工单类型所有字段
   * 工单类型变化之后的事件
   * 1. 获取工单类型字段
   * 2. 获取工单类型回执字段
   * 3. 获取用户开启的配置节点 以及工单搜索范围 和 异常原因字段值
   * 4. 构建高级搜索列
   * @return {void}
   */  
  public async initializeTaskTypeAllFields(): Promise<void> {
    // 获取工单类型字段
    await this.fetchTaskFields()
    // 获取工单类型回执字段
    await this.fetchTaskReceiptFields()
    // 获取用户开启的配置节点 以及工单搜索范围 和 异常原因字段值
    await this.fetchTurnOnTaskExceptionNodeInfo()
    // 构建高级搜索列
    this.buildAdvancedColumns()
  }

  /**
   * @description 构建高级搜索列
   */
  public buildAdvancedColumns() {
    this.advanceSearchColumns = [
      ...this.getAdvancedFields(this)
    ]
  }
  
  
  /**
   * @description 打开审批弹窗
   * @param {*} data
   * @return {void}
   */  
  private openProposeApproveDialog(approveData: TaskApprove): void {
    // @ts-ignore
    this.ProposeApproveDialogComponent?.openDialog(approveData)
  }
  
  private renderApproveDialogComponent(): VNode {
    return (
      <propose-approve-dialog 
        ref='ProposeApproveDialogComponent'
        remarkRequired={this.taskConfig?.approveRemark}
        taskId={this.taskApproveId} 
        taskNo={this.taskNo} 
      />
    )
  }
  
  /**
   * @description: 渲染批量关闭按钮
   * @return {VNode}
   */ 
  public renderBatchCloseButton(): VNode {
    return (
      <permission auth={this.allowTaskBatchClose}>
        <el-button type='primary' onClick={() => this.batchCloseTaskHandler()}>
          {i18n.t('task.taskTypes.close.batchClose')}
        </el-button>
      </permission>
    )
  }
  
  /**
   * @description: 渲染表格作用域插槽
   * @return {VNode | null} 插槽或空
   */  
  public renderTableScopedSlot(): Record<string, (data: BizTableTaskScopeSlot) => JSX.Element | null>| null {
    // 保存this指向
    const _this = this
    
    return {
      // 关闭操作
      closeOperation: ({ value }: BizTableTaskScopeSlot) => {
        // 工单已关闭
        if (isClosedTask(value)) {
          return (
            <el-button disabled type='text' size='small' class='closed-task-button'>
              {i18n.t('common.task.type.closed')}
            </el-button>
          )
        }
        
        // 审批的中的工单不显示关闭按钮
        if (isInApprove(value)) return null
        
        return (
          <el-button
            class='close-task-button'
            type='text'
            size='small'
            onClick={() => _this.closeTask(value)}
          >
            {i18n.t('common.base.close')}
          </el-button>
        )
      }
    }
  }
  
  /**
   * @description: 渲染操作区域容器
   * @return {VNode}
   */ 
  public renderOperationContainer(): VNode {
    return (
      <div ref="tableDoContainer" class='common-list-view__v2 mt_12 operation-container pad-b-none'>
        <div class='common-list-view-header__v2 task-ai'>
          <div class='common-list-view-header__v2-left task-ai'>
            { this.renderBatchCloseButton() }
          </div>
          <div class='common-list-view-header__v2-right task-ai'>
            { this.renderSelectColumnsButton() }
          </div>
        </div>
      </div>
    )
  }
  
  /**
   * @description: 渲染其他组件容器
   * @return {VNode}
   */ 
  public renderComponentsContainer(): VNode {
    return (
      <div>
        {/* { this.renderAdvancedSearchPanel() } */
        this.renderAdvancedSearchPanelAllot()
        }
        { this.renderSelectColumnComponent() }
        { this.renderSelectionPanelComponent() }
        { this.renderApproveDialogComponent() }
      </div>
    )
  }

  public refresh() {
    this.loading = true
    setTimeout(async() => {
      // 清空已选中数据
      this.BizTableComponent?.outsideClearSelection()
      this.multipleSelection = []
      // 重新更新列表数据
      await this.search()
      // this.loading = false
    }, 1000)
  }
  public computedListPxArray(){
    let padding = [24, 16, 16]
    return padding;
  }
  public changePackUpLocal(){
    this.changePackUp()
  }
  
  async mounted() {
    // 恢复常用
    this.recoverCommonUse()
    // 获取初始化数据
    await this.fetchInitData()
    // 获取关闭工单列表
    this.search()
    // 初始化工单字段列表
    this.initializeTaskTypeAllFields()
    // [tab_spec]标准化刷新方式
    window.__exports__refresh = async () => {
      setTimeout(() => {
        this.search()
      }, 1000)
    }
    let that_ = this;
    // 监听切换后需要重新计算列表高度
    window.addEventListener('message', (event:any)=> {
      const {action, data} = event.data;
      if (action == 'shb.frame.activatedPage'){
        (that_ as any).$nextTick(()=> {
          (that_ as any).knowTableContainerHeight();
        })
      }
    });
    (this as any).$nextTick(()=> {
      (this as any).knowTableContainerHeight()
      window.onresize = _.debounce(()=>{
        (that_ as any).knowTableContainerHeight()
      }, 500)
    })
  }
  
  render(h: CreateElement) {
    // 属性列表
    const attrs = this.getAttributes()
    
    return (
      <div {...attrs}>
        { this.renderHeaderContainer() }
        { this.renderOperationContainer() }
        { this.renderContentContainer() }
        { this.renderComponentsContainer() }
      </div>
    )
    
  }

  public packUp = true
  /**
   * @description: 渲染头部容器
   * @return {VNode}
   */ 
  public renderHeaderContainer(): VNode {
    return (
      <div ref="tableHeaderContainer" class='header-container'>
        <div class='common-list-header__v2'>
          <div class="search-container">
            { this.renderSearchContainer() }
           </div>
          { this.renderAdvancedSearchButton() }
        </div>

        {this.packUp?<div class="task-type-filter">
          <div class="task-list-header-nav">
            <div class="task-filter-item">
              <div class="task-font14 task-c7 state">{i18n.t('common.task.taskType')}：</div>
              <div class="list" >
                <div class="list-item task-flex task-ai">
                  {[...[{name:i18n.t('common.base.all'),id:undefined}],...this.taskTypes].map((item:any)=>{
                    return (item.id == this.currentTaskType?.id )?<div class="task-nav-create task-c2 task-padding-0" onClick={() => this.changeTaskType(item)}>
                      <div class="actived" title={item.name}>{item.name}</div>
                    </div>: <div class="task-nav-create" onClick={() => this.changeTaskType(item)}>
                      <span title={item.name}>{item.name}</span>
                    </div>
                  })}
                </div>
              </div>
            </div>
          </div>
          </div>:null}
          <div class="pack-up">
            <div onClick={() => this.changePackUpLocal()}>
              {this.packUp?<i class="iconfont icon-Icon_up"></i>:<i class="iconfont icon-more" ></i>}
            </div>
          </div>
      </div>
    )
  }

  public changeTaskType(item:any){
    // @ts-ignore
    this.$track.clickStat(this.$track.formatParams('QUICK_SEARCH', '工单类型'));

    const {name,id}=item
    this.currentTaskType={
      id,
      name,
      templateId:id
    }
    this.initializeTaskTypeAllFields()
    this.refresh()
  }

  /**
   * 高级搜索
   * @param searchModel
   */
  public handleAdvancedSearch(searchModel: any = {}){
    this.advancedSearchModel = searchModel;
    this.search();
  }

  /**
   * 常用字段切换
   * @param {*} fieldName
   * @param {*} isChecked
   */
  public changeCommonUse({fieldName, isChecked}: commonUseItemType){
    const inCommonUseSet = new Set(this.inCommonUse)
    if(isChecked){
      inCommonUseSet.add(fieldName)
    }else {
      inCommonUseSet.delete(fieldName);
    }
    this.inCommonUse = Array.from(inCommonUseSet);
    try {
      StorageUtil.storageSet(this.advancedSearchFieldStorageKey, this.inCommonUse, StorageModuleEnum.Task)
    } catch (error) {
      console.error('changeCommonUse ~ setIndexedDbData ~ error', error)
    }
  }

  /**
   * 恢复常用字段
   */
  public async recoverCommonUse(){
    try {
      this.inCommonUse = await StorageUtil.storageGet(this.advancedSearchFieldStorageKey, [], StorageModuleEnum.Task)
    } catch (error) {
      console.error('获取常用字段 recoverCommonUse', error);
      return Promise.reject(error)
    }
  }
  
}

